package de.szut.ita13.sommerfeld.loganalyser;

import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Point;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

public class GUI extends Frame {
	
	private static final long serialVersionUID = 1L;
	private final int[] offsetButton = {200,50};
	private final int[] offsetLabel = {600,25};
	private Button openLog;
	private Button resetAnalyser;
	private Button analyseLog;
	
	private TextField search;
	private Label searchLabel;
	private Button searchButton;
	
	private Label statusLabel;
	
	public static final String[][] LABELNAME = {{"Total Logs:","Total Resources:","Total Resource Size:","Total Users:","First Log Time:","Last Log Time:","Time Elapsed:",
												"GET:","POST:","PROPFIND:","HEAD:","CONNECT:","LOCK:","UNLOCK:","OPTIONS:"},
												{"-","-","-","-","-","-","-","-","-","-","-","-","-","-","-"}};
	private Label[][] labels; 
	
	public static ArrayList apacheLogs;
	private LogHandler loghandler;
	private FileDialog filedialog;
	
	public GUI (String title) {
		setTitle(title);
		setLayout(null);
		setResizable(false);
		setSize(new Dimension(900,500));
		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent we) {
				System.exit(0);
			}
		});
		
		apacheLogs = new ArrayList();
		
		filedialog = new FileDialog(new Frame(), "Log Analyser");
		filedialog.setDirectory("C:\\");
		filedialog.setFile("*.log");
		
		openLog = new Button("Open Log");
		openLog.setSize(new Dimension(offsetButton[0], offsetButton[1]));
		openLog.setLocation(new Point(0, getHeight() - openLog.getHeight()));
		openLog.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					openLog();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}	
		});
		openLog.setVisible(true);
		
		resetAnalyser = new Button("Reset Analyser");
		resetAnalyser.setSize(new Dimension(offsetButton[0], offsetButton[1]));
		resetAnalyser.setEnabled(false);
		resetAnalyser.setLocation(new Point(getWidth() / 2 - resetAnalyser.getWidth() / 2, getHeight() - resetAnalyser.getHeight()));
		resetAnalyser.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				resetAnalyser();	
			}
			
		});
		
		analyseLog = new Button("Analyse Log");
		analyseLog.setSize(new Dimension(offsetButton[0], offsetButton[1]));
		analyseLog.setLocation(new Point(getWidth() - analyseLog.getWidth(), getHeight() - analyseLog.getHeight()));
		analyseLog.setEnabled(false);
		analyseLog.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				try {
					analyseLog();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
		analyseLog.setVisible(true);
		
		labels = new Label[LABELNAME[0].length][2];
		for(int i = 0; i < labels.length; i++) {
			for(int j = 0; j < labels[i].length; j++) {
				labels[i][j] = new Label(LABELNAME[j][i]);
				labels[i][j].setSize(new Dimension(150, 25));
				labels[i][j].setLocation(new Point((25 + labels[i][j].getWidth() * j + labels[i][j].getWidth() * (2 * (i / (labels.length / 2)))), 35 + labels[i][j].getHeight() * (i % (labels.length / 2))));
				labels[i][j].setVisible(true);
				add(labels[i][j]);
			}
		}
		
		statusLabel = new Label();
		statusLabel.setText("Select a log file to analyse");
		statusLabel.setSize(new Dimension(offsetLabel[0],offsetLabel[1]));
		statusLabel.setLocation(new Point(10, labels[6][0].getY() + labels[6][0].getHeight() + 20));
		statusLabel.setVisible(true);
		
		search = new TextField();
		search.setSize(new Dimension(250,25));
		search.setLocation(new Point(10, getHeight() - openLog.getHeight() - search.getHeight() - 20));
		search.setEnabled(false);
		search.setVisible(true);
		
		searchLabel = new Label("IP Search - Search for an user via IP");
		searchLabel.setSize(new Dimension(250,25));
		searchLabel.setLocation(new Point(10, search.getY() - searchLabel.getHeight()));
		searchLabel.setVisible(true);
		
		searchButton = new Button("Search");
		searchButton.setSize(new Dimension(offsetButton[0], 25));
		searchButton.setLocation(new Point(searchLabel.getX() + searchLabel.getWidth() + 5, search.getY()));
		searchButton.setEnabled(false);
		searchButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(search.getText().isEmpty() || !loghandler.isValidIP(search.getText()))
					changeStatusLabelState(statusLabel, "search string is empty or an invalid ip", Color.RED);
				else
					loghandler.searchForAnUser(search.getText()).setVisible(true);
			}
		});
		searchButton.setVisible(true);
		
		add(statusLabel);
		add(openLog);
		add(resetAnalyser);
		add(analyseLog);
		add(search);
		add(searchLabel);
		add(searchButton);
	}
	
	private boolean openLog() throws FileNotFoundException, IOException {
		filedialog.setVisible(true);
		if(filedialog.getFile() != null && filedialog.getFile().endsWith(".log")) {
			loghandler = new LogHandler(new File(filedialog.getDirectory() + "/" + filedialog.getFile()));
			if(loghandler.hasValidSignature()) {
				changeStatusLabelState(statusLabel, "log file has got a valid signature", Color.BLUE);
				changeButtonState(false,true,true,false);
			}
			else {
				changeStatusLabelState(statusLabel, "log file has got an invalid signature", Color.RED);
				changeButtonState(false,true,false,false);
			}
			
			return true;
		}
		else {
			changeStatusLabelState(statusLabel, "canceled or wrong file format", Color.RED);
			return false;
		}
	}
	
	private void analyseLog() throws FileNotFoundException, IOException {
		if(loghandler.getFile() != null && loghandler.fileIsLog()) {
			changeButtonState(false,false,false,false);
			changeStatusLabelState(statusLabel, "Analysing Log...", Color.BLACK);
			ApacheLog apachelog = loghandler.analyseLog();
			for(int i = 0; i < apachelog.getStats().size(); i++) {
				labels[i][1].setText(apachelog.getStats().get(i).toString());
			}
			apacheLogs.add(apachelog);
			changeStatusLabelState(statusLabel,"Analysing done!", Color.GREEN);
			changeButtonState(false,true,false,true);
		} else {
			changeStatusLabelState(statusLabel, "not able to analyse log file", Color.RED);
		}
	}
	
	private void resetAnalyser() {
		if(loghandler.getFile() != null) {
			loghandler.setFile(null);
			changeStatusLabelState(statusLabel,"Select a log file to analyse", Color.BLACK);
			for(int i = 0; i < labels.length; i++)
				labels[i][1].setText(LABELNAME[1][i]);
			for(int i = 0; i < LogHandler.requests.length; i++)
				LogHandler.requests[i] = 0;
			LogHandler.resourcesize = 0;
			LogHandler.logcount = 0;
			LogHandler.timer = 0;
			LogHandler.allUser = new HashMap();
			search.setText("");
			changeButtonState(true,false,false,false);
		}
	}

	private void changeButtonState(boolean open, boolean clear, boolean analyse, boolean searchBtn) {
		openLog.setEnabled(open);
		resetAnalyser.setEnabled(clear);
		analyseLog.setEnabled(analyse);
		searchButton.setEnabled(searchBtn);
		search.setEnabled(searchBtn);
	}
	
	private void changeStatusLabelState(Label label,String text, Color color) {
		label.setText(text);
		label.setForeground(color);
	}
}
